unit GLGUIUtils;

interface

uses
  Dialogs,
  StrUtils,
  SysUtils,
  Classes,
  GLTexture,
  VectorGeometry,
  VectorTypes,
  GLGUIEvent,
  GLGUITokens,
  GLGUIKeys;

function IntToStr(Value: Integer): string;
function FloatToStr(Value: Single; Digits: Integer = 6): string;
function StrToInt(const Str: string; Def: Integer = 0): Integer;
function StrToFloat(const Str: string; Def: Single = 0): Single;
function StringToGUIState(AString: String): TGLGUIState;

function StringToVector2f(AString: String): TVector2f;
function Vector2fToString(const AVector: TVector2f): String;

function StringToVector3f(AString: String): TVector3f;
function Vector3fToString(const AVector: TVector3f): String;

function StringToVector4f(AString: String): TVector;
function Vector4fToString(const AVector: TVector): String;

function StringToGUIPart(AString: String): TGLGUIPart;
function StringToAlign(AString: String): TGLGUIAlign;
function StringToKeyClass(AString: String): TGLGUIKeyClass;
function SameStr(const S1, S2: string): Boolean;
function ScreenToOpenGL(const AScreenX, AScreenY, AScreenWidth, AScreenHeight: Single): TVector2f;
function VectorToString(const AVector: TVector): String; overload;
function VectorToString(const AVector: TVector4i): String; overload;
function MatrixToString(const AMatrix: TMatrix; ALine: Boolean = True): String;

type
  TGLGUISides = class(TComponent)
  protected
    FTop: Single;
    FBottom: Single;
    FLeft: Single;
    FRight: Single;
    procedure SetTop(const AValue: Single);
    procedure SetBottom(const AValue: Single);
    procedure SetLeft(const AValue: Single);
    procedure SetRight(const AValue: Single);
    procedure SetValue(const AValue: Single);
  public
    property Top: Single read FTop write SetTop;
    property Bottom: Single read FBottom write SetBottom;
    property Left: Single read FLeft write SetLeft;
    property Right: Single read FRight write SetRight;
    property Value: Single write SetValue;
  end;

  TGLGUIInheritance = class
  public
    Alpha: Boolean;
    Color: Boolean;
    FillColor: Boolean;
    WorkState: Boolean;
    Visibility: Boolean;
    procedure All;
    procedure None;
  end;

  TGLGUIInheriranceParams = class
  public
    Transmit: TGLGUIInheritance;
    Inherit: TGLGUIInheritance;
    constructor Create;
    destructor Destroy; override;
  end;

  type TGLGUISize = record
    Width: Single;
    Height: Single;
  end;

  type TGLGUISizeInt = record
    Width: Integer;
    Height: Integer;
  end;

implementation

uses
  GLGUIBase,
  GLGUI2DSprite,
  GLGUIEventManager;

type
  TGLGUIObjectAccessProvider = class(TGLGUIObject)
  end;

{$IFDEF GLS_REGIONES}{$REGION 'Const'}{$ENDIF}

const
  GUIStatesStrings: Array [low(TGLGUIState) .. high(TGLGUIState)] of String =
    (
      'Enabled',
      'Disabled',
      'Focused',
      'Selected',
      'EnabledChecked',
      'DisabledChecked',
      'FocusedChecked',
      'SelectedChecked'
    );

  GUIPartsStrings: Array [low(TGLGUIPart) .. high(TGLGUIPart)] of String =
    (
    'Center',
    'Top',
    'Bottom',
    'Left',
    'Right',
    'TopLeft',
    'TopRight',
    'BottomLeft',
    'BottomRight'
    );

  GUIAlignsStrings: Array [low(TGLGUIAlign) .. high(TGLGUIAlign)] of String =
    (
      'galNone',
      'galCenter',
      'galTop',
      'galTopStretch',
      'galBottom',
      'galBottomStretch',
      'galLeft',
      'galLeftStretch',
      'galRight',
      'galRightStretch',
      'galLeftTop',
      'galRightTop',
      'galLeftBottom',
      'galRightBottom',
      'galClient',
      'galFill',
      'galHorizontal'
    );

  TGLGUITypesStrings: Array [0 .. 2] of String =
    (
    'Int',
    'Float',
    'Vec4'
    );

  TGLGUITypesKeys: Array [0 .. 2] of TGLGUIKeyClass =
    (
    TGLGUIKeyInt,
    TGLGUIKeyFloat,
    TGLGUIKeyVec4f
    );

{$IFDEF GLS_REGIONES}{$ENDREGION}{$ENDIF}

procedure TGLGUIInheritance.All;
begin
  Alpha := True;
  Color := True;
  FillColor := True;
  WorkState := True;
  Visibility := True;
end;

procedure TGLGUIInheritance.None;
begin
  Alpha := False;
  Color := False;
  FillColor := False;
  WorkState := False;
  Visibility := False;
end;


constructor TGLGUIInheriranceParams.Create;
begin
  Transmit := TGLGUIInheritance.Create;
  Inherit := TGLGUIInheritance.Create;
end;

destructor TGLGUIInheriranceParams.Destroy;
begin
  Transmit.Free;
  Inherit.Free;
  inherited;
end;

function IntToStr(Value: Integer): String;
begin
  Str(Value, Result);
end;

function FloatToStr(Value: Single; Digits: Integer = 6): String;
begin
  Str(Value:0:Digits, Result);
end;

function StrToInt(const Str: string; Def: Integer = 0): Integer;
var
  Code : Integer;
begin
  Val(Str, Result, Code);
  if Code <> 0 then
    Result := Def;
end;

function StrToFloat(const Str: string; Def: Single = 0): Single;
var
  Code : Integer;
begin
  Val(Str, Result, Code);
  if Code <> 0 then
    Result := Def;
end;

function StringToGUIState(AString: String): TGLGUIState;

{$IFDEF GLS_REGIONES}{$REGION 'GuiStateIndex'}{$ENDIF}

  function GuiStateIndex: Integer;
  begin
    Result := AnsiIndexStr(AString, GUIStatesStrings);
  end;

{$IFDEF GLS_COMPILER_2005_UP}{$ENDREGION}{$ENDIF}

begin
  Result := TGLGUIState(GuiStateIndex);
end;

function StringToVector2f(AString: String): TVector2f;
var
  A1,A2:integer;
  F:single;
  s: String;
  c: Char;
  FS: TFormatSettings;
  i, j, l: Integer;
begin
  FS.DecimalSeparator:='.';
  Result:=Vector2fMake(0,0);
  A1:=1;
  A2:=Pos(',', AString);
  if A2=0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2-A1), F, FS) then
    Result[0]:=F;
  A1:=A2+1;
  if TryStrToFloat(Copy(AString, A1, Length(AString) + 1 - A1), F, FS) then
    Result[1]:=F;
end;

function Vector2fToString(const AVector: TVector2f): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]);
end;

function StringToVector3f(AString: String): TVector3f;
var
  A1,A2:integer;
  F:single;
  FS: TFormatSettings;
begin
  FS.DecimalSeparator:='.';
  Result:=XYZVector;
  A1:=1;
  A2:=Pos(',', AString);
  if A2=0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2-A1), F, FS) then
    Result[0]:=F;
  A1:=A2+1;
  A2:=PosEx(',', AString, A1);
  if A2=0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2-A1), F, FS) then
    Result[1]:=F;
  A1:=A2+1;
  if TryStrToFloat(Copy(AString, A1, Length(AString) + 1 - A1), F, FS) then
    Result[2]:=F;
end;

function Vector3fToString(const AVector: TVector3f): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]) + ',';
  Result := Result + FloatToStr(AVector[2]);
end;

function StringToVector4f(AString: String): TVector;
var
  A1,A2:integer;
  F:single;
  FS: TFormatSettings;
begin
  FS.DecimalSeparator:='.';
  Result:=XYZWHmgVector;
  A1:=1;
  A2:=Pos(',', AString);
  if A2=0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2-A1), F, FS) then
    Result[0]:=F;
  A1:=A2+1;
  A2:=PosEx(',', AString, A1);
  if A2=0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2-A1), F, FS) then
    Result[1]:=F;
  A1:=A2+1;
  A2:=PosEx(',', AString, A1);
  if A2=0 then
    Exit;
  if TryStrToFloat(Copy(AString, A1, A2-A1), F, FS) then
    Result[2]:=F;
  A1:=A2+1;
  if TryStrToFloat(Copy(AString, A1, Length(AString) + 1 - A1), F, FS) then
    Result[3]:=F;
end;

function Vector4fToString(const AVector: TVector): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]) + ',';
  Result := Result + FloatToStr(AVector[2]) + ',';
  Result := Result + FloatToStr(AVector[3]);
end;

function StringToKeyClass(AString: String): TGLGUIKeyClass;
{$IFDEF GLS_REGIONES}{$REGION 'ClassIndex'}{$ENDIF}
function ClassIndex: Integer;
  begin
    Result := AnsiIndexStr(AString, TGLGUITypesStrings);
  end;
{$IFDEF GLS_REGIONES}{$ENDREGION}{$ENDIF}
begin
  Result := TGLGUITypesKeys[ClassIndex];
end;

function StringToGUIPart(AString: String): TGLGUIPart;

{$IFDEF GLS_REGIONES}{$REGION 'GuiPartIndex'}{$ENDIF}
  function GuiPartIndex: Integer;
  begin
    Result := AnsiIndexStr(AString, GUIPartsStrings);
  end;
{$IFDEF GLS_REGIONES}{$ENDREGION}{$ENDIF}

begin
  Result := GLGUIPartCenter;
  case GuiPartIndex of
    0:
      Result := GLGUIPartCenter;
    1:
      Result := GLGUIPartTop;
    2:
      Result := GLGUIPartBottom;
    3:
      Result := GLGUIPartLeft;
    4:
      Result := GLGUIPartRight;
    5:
      Result := GLGUIPartTopLeft;
    6:
      Result := GLGUIPartTopRight;
    7:
      Result := GLGUIPartBottomLeft;
    8:
      Result := GLGUIPartBottomRight;
  end;
end;

function StringToAlign(AString: String): TGLGUIAlign;
begin
  Result := TGLGUIAlign(AnsiIndexStr(AString, GUIAlignsStrings));
end;

function SameStr(const S1, S2: string): Boolean;
{$IFDEF FPC}
begin
{$ASMMODE intel}
{$ENDIF}
asm
    CMP     EAX,EDX
    JZ      @1
    OR      EAX,EAX
    JZ      @2
    OR      EDX,EDX
    JZ      @3
    MOV     ECX,[EAX-4]
    CMP     ECX,[EDX-4]
    JNE     @3
{$IFDEF ALIGN_STACK}
    SUB     ESP, 12
{$ENDIF ALIGN_STACK}
    CALL    CompareStr
{$IFDEF ALIGN_STACK}
    ADD     ESP, 12
{$ENDIF ALIGN_STACK}
    TEST    EAX,EAX
    JNZ     @3
@1: MOV     AL,1
@2: RET
@3: XOR     EAX,EAX
end;
{$IFDEF FPC}
end;
{$ENDIF}

function ScreenToOpenGL(const AScreenX, AScreenY, AScreenWidth,
  AScreenHeight: Single): TVector2f;
begin
  Result[0] := 2 * AScreenX / AScreenWidth - 1;
  Result[1] := 2 * (1 - AScreenY / AScreenHeight) - 1;
end;

function VectorToString(const AVector: TVector): String;
begin
  Result := '';
  Result := Result + FloatToStr(AVector[0]) + ',';
  Result := Result + FloatToStr(AVector[1]) + ',';
  Result := Result + FloatToStr(AVector[2]) + ',';
  Result := Result + FloatToStr(AVector[3]);
end;

function VectorToString(const AVector: TVector4i): String;
begin
  Result := '';
  Result := Result + IntToStr(AVector[0]) + ',';
  Result := Result + IntToStr(AVector[1]) + ',';
  Result := Result + IntToStr(AVector[2]) + ',';
  Result := Result + IntToStr(AVector[3]);
end;

function MatrixToString(const AMatrix: TMatrix; ALine: Boolean = True): String;
var
  vRowSeparator: String;
begin
  Result := '';
  if ALine then
    vRowSeparator := '  ,  '
  else
    vRowSeparator := #13;
  Result := Result + VectorToString(AMatrix[0]) + vRowSeparator;
  Result := Result + VectorToString(AMatrix[1]) + vRowSeparator;
  Result := Result + VectorToString(AMatrix[2]) + vRowSeparator;
  Result := Result + VectorToString(AMatrix[3]);
end;

procedure TGLGUISides.SetTop(const AValue: Single);
begin
  FTop := AValue;
  if Assigned(Owner) then
    TGLGUI2DSpriteCustom(Owner).NotifyGUIChange(Self);
end;

procedure TGLGUISides.SetBottom(const AValue: Single);
begin
  FBottom := AValue;
  if Assigned(Owner) then
    TGLGUI2DSpriteCustom(Owner).NotifyGUIChange(Self);
end;

procedure TGLGUISides.SetLeft(const AValue: Single);
begin
  FLeft := AValue;
  if Assigned(Owner) then
    TGLGUI2DSpriteCustom(Owner).NotifyGUIChange(Self);
end;

procedure TGLGUISides.SetRight(const AValue: Single);
begin
  FRight := AValue;
  if Assigned(Owner) then
    TGLGUI2DSpriteCustom(Owner).NotifyGUIChange(Self);
end;

procedure TGLGUISides.SetValue(const AValue: Single);
begin
  FTop := AValue;
  FBottom := AValue;
  FLeft := AValue;
  FRight := AValue;
  if Assigned(Owner) then
    TGLGUI2DSpriteCustom(Owner).NotifyGUIChange(Self);
end;

initialization
finalization
end.
